<?php
/**
 * @brief Klasa mapująca dane z bazy danych na obiekty klasy encyjnej Application_Model_Offer.
 *
 * Obiekty tej klasy pośredniczą wymianie danych między bazą danych a obiektami klasy Application_Model_Offer.
 * Za pomocą metod z przypisanej klasy tabeli tworzą obiekty na podstawie danych z bazy danych 
 * oraz zapisują informacje z obiektów do bazy danych.
 * 
 */
class Application_Model_OfferMapper
{
    protected $_dbTable; /*!<  Obiekt klasy tabeli */
    
    /**
     * @brief Metoda do ustawiania nazwy powiązanej klasy tabel o podanej nazwie.
     * 
     * @param string $dbTable
     * @return Application_Model_OfferMapper 
     */
    public function setDbTable($dbTable) {

        if (is_string($dbTable)) {

            $dbTable = new $dbTable();
        }

        if (!$dbTable instanceof Zend_Db_Table_Abstract) {

            throw new Exception('Invalid table data gateway provided');
        }

        $this->_dbTable = $dbTable;

        return $this;
    }

    /**
     * @brief Metoda zwracająca obiekt powiązanej klasy tabel.
     * 
     * @return Application_Model_DbTable_Offer 
     */
    public function getDbTable() {

        if (null === $this->_dbTable) {

            $this->setDbTable('Application_Model_DbTable_Offer');
        }

        return $this->_dbTable;
    }

    /**
     * @brief Metoda zapisująca informacje do bazy danych  z obiektu reprezentującego 
     *
     * Metoda służy zarówno do tworzenia w bazie danych nowych rekordów, jak i aktualizacji starych. 
     * Aktualizacja następuje w przypadku, gdy obiekt posiada już indywidualny identyfikator.
     * 
     * @param Application_Model_Offer $offer
     * @return int 
     */
    public function save(Application_Model_Offer $offer) {

        $data = array(
            'Auction_id'        =>$offer->getAuction_id(),
            'MarketEntity_id'   =>$offer->getMarketEntity_id(),
            'minVolume'         =>$offer->getMinVolume(),
            'maxVolume'         =>$offer->getMaxVolume(),
            'offeredPrice'      =>$offer->getOfferedPrice(),
            'acceptedVolume'    =>$offer->getAcceptedVolume(),
            'firstOffer'        =>$offer->getFirstOffer(),
            'ownerGroup_id'     =>$offer->getOwnerGroup_id(),
            'headOffer_id'      =>$offer->getHeadOffer_id(),
        );



        if (null === ($id = $offer->getOffer_id())) { 

            unset($data['Offer_id']);

            $newId = $this->getDbTable()->insert($data);
            return $newId;
        } else {

            $this->getDbTable()->update($data, array('Offer_id = ?' => $id));
            return $id;
        }
    }

    /**
     * @brief Metoda wyszukująca ofertę na podstawie identyfikatora.
     *
     * Metoda generuje pojedynczy obiekt reprezentujący ofertę na podstawie rekordu, o podanym
     * identyfikatorze, znalezionego w bazie danych.
     * 
     * @param int $id
     * @return Application_Model_Offer | null
     */
    public function find($id) { 
	$offer = new Application_Model_Offer();    
        $result = $this->getDbTable()->find($id);

        if (0 == count($result)) {

            return;
        }

        $row = $result->current();

        $offer->setOffer_id($row->Offer_id);
        $offer->setAuction_id($row->Auction_id);
        $offer->setMarketEntity_id($row->MarketEntity_id);
        $offer->setMaxVolume($row->maxVolume);
        $offer->setMinVolume($row->minVolume);
        $offer->setAcceptedVolume($row->acceptedVolume);
        $offer->setOfferedPrice($row->offeredPrice);
        $offer->setFirstOffer($row->firstOffer);
        
        $offer->setHeadOffer_id($row->headOffer_id);
        $offer->setOwnerGroup_id($row->ownerGroup_id);
            
               

        return $offer;
    }
    
    /**
     * @brief Metoda wyszukująca zbiór ofert na podstawie danych wejściowych.
     *
     * Metoda wyszukuje zbiór ofert  i zwraca tablicę obiektów Application_Model_Offer. 
     * Zbiór rekordów uzyskanych z klasy tabel jest przetwarzany przez inną metodę.
     * 
     * @param string $query
     * @return array Application_Model_Offer 
     */
    public function fetchAll($query = NULL) {
        if ($query === NULL) {
            $resultSet = $this->getDbTable()->fetchAll();
            
        } else {
            $table = $this->getDbTable();
            $select = $table->select();
            $select->from($table)
                    ->where($query);

            $resultSet = $this->getDbTable()->fetchAll($select);
        }
        return $this->processResultSet($resultSet);
    }
    
    public function delete($offerId) {
        $query = 'Offer_id = '.$offerId;
        $this->getDbTable()->delete($query);
    }
	
    /**
     * @brief Metoda przetwarza rekordy na obiekty.
     * 
     * @param Zend_Db_Table_Rowset $resultSet
     * @return array Application_Model_Offer 
     */
    private function processResultSet($resultSet) {
        $entries = array();
        foreach ($resultSet as $row) {

            $offer = new Application_Model_Offer();

            $offer->setOffer_id($row->Offer_id);
            $offer->setAuction_id($row->Auction_id);
            $offer->setMarketEntity_id($row->MarketEntity_id);
            $offer->setMaxVolume($row->maxVolume);
            $offer->setMinVolume($row->minVolume);
            $offer->setAcceptedVolume($row->acceptedVolume);
            $offer->setOfferedPrice($row->offeredPrice);
            $offer->setFirstOffer($row->firstOffer);
            
            $offer->setHeadOffer_id($row->headOffer_id);
            $offer->setOwnerGroup_id($row->ownerGroup_id);
            
            $entries[] = $offer;
        }
        return $entries;
    }
    
    /**
     * @brief Metoda zlicza rekordy odpowiadających podanym kryteriom.
     * 
     * @param string $query
     * @return int
     */
    public function count($query = NULL)
    {
        $table = $this->getDbTable();
        $select = $table->select();
        $select->from($table,array('count(*) as amount'));
        if($query != NULL)
        $select->where($query);
        $rows = $table->fetchAll($select);
        return($rows[0]->amount); 
    }
    
    /**
     * @brief Metoda wyszukująca oferty o podanym statusie.
     *
     * Metoda umożliwia wyszukanie ofert użytkownika , które w danej chwili mają określony status.
     * Metoda uwzględnia również rozdział na oferty wyjściowe oraz zwykłe oferty.
     *
     * @param string $status Status oferty
     * @param string $user Nazwa uzytkownika
     * @param string $scope 'Otwarte' | 'Zamknięte'
     * @param string $endTime Ostatecznu czas końca statusu oferty (YYYY MM dd HH:ss)
     * @return Application_Model_Offer 
     */
    public function fetchOfferbyStatus($status,$user,$scope=NULL,$endTime=NULL)
    {
        $db = Zend_Db_Table::getDefaultAdapter();
        $select = $db->select();
        $select->from(array('o'=>'offer'));
        $select->join(array('s'=>'offer_has_offerstatus'),'s.Offer_id = o.Offer_id');
        $select->where('o.MarketEntity_id = ?',$user);
        $select->where('s.status = ?',$status);
        
        if(isset ($scope)){
            if($scope == 'offers'){
                $select->where('o.firstOffer = ?', 0);
            } elseif($scope == 'auctions') {
                $select->where('o.firstOffer = ?', 1);
            }
        }
        
        $select->where('s.startTime < now()');
        
        
        if(isset($endTime)){
            $select->where('s.endTime > ?', $endTime);  
        } else {
            $select->where('s.endTime > now()');
        }
        $select->order('s.endTime');
        
        $resultSet = $db->fetchAll($select);
        $results = array();
        foreach ($resultSet as $key=>$value) {
            $results[] = new Application_Model_Offer($value);
        }
        
        return $results;
    }
    
    public function fetchOfferByGroup($groupId) {
        $query = "ownerGroup_id = $groupId";
        return $this->fetchAll($query);                
    }
    
    public function fetchOfferByAuctionAndComponent($auction, $commodity, $share) {
        $db = Zend_Db_Table::getDefaultAdapter();
        $select = $db->select();
        $select->from(array('o'=>'offer'));
        $select->join(array('c'=>'offer_has_commodity'),'c.Offer_id = o.Offer_id');
        $select->where('o.Auction_id = ?',$auction);
        $select->where('c.shareFactor = ?',$share);
        $select->where('c.Commodity_id = ?',$commodity);
        
        $resultSet = $db->fetchAll($select);
        $results = array();
        foreach ($resultSet as $key=>$value) {
            $results[] = new Application_Model_Offer($value);
        }
        
        return $results;
    }

}

